<template>
  <div style="width: 100%">
    <editor :id="editorId" v-model="content" :init="init" :disabled="disabled">
    </editor>
    <div v-if="maxlength>0" class="text-length-wrapper">
        <span class="text-length"
              :style="{color:textLength>maxlength?'red':'#ccc'}">{{ `${textLength} / ${maxlength}` }}</span>
    </div>
  </div>
</template>

<script>
import { VITE_APP_UPLOAD_URL} from '@/api/upload'
import {getToken} from "@/utils/auth";
import {uploadFile} from "@/api/common";
import {MessagePlugin} from 'tdesign-vue';
import tinymce from 'tinymce'
import Editor from '@tinymce/tinymce-vue'
import 'tinymce/icons/default/icons.min.js'
import 'tinymce/plugins/image' // 插入上传图片插件
import 'tinymce/plugins/media' // 插入视频插件
import 'tinymce/plugins/table' // 插入表格插件
import 'tinymce/plugins/lists' // 列表插件
import 'tinymce/plugins/wordcount' // 字数统计插件
import 'tinymce/themes/silver/theme.min.js'
import 'tinymce/skins/ui/oxide/skin.min.css'
import 'tinymce/skins/ui/oxide/content.min.css'
import 'tinymce/plugins/preview/plugin.min.js'
import 'tinymce/plugins/colorpicker/plugin.min.js'
import 'tinymce/plugins/advlist/plugin.min.js'
import 'tinymce/plugins/autolink/plugin.min.js'
import 'tinymce/plugins/link/plugin.min.js'
import 'tinymce/plugins/image/plugin.min.js'
import 'tinymce/plugins/lists/plugin.min.js'
import 'tinymce/plugins/fullscreen/plugin.min.js'
import 'tinymce/plugins/wordcount/plugin.min.js'
import 'tinymce/plugins/code/plugin.min.js'
import 'tinymce/plugins/print/plugin.min.js'
import 'tinymce/plugins/imagetools/plugin.min.js'
import 'tinymce/plugins/table/plugin.min.js'
import 'tinymce/plugins/quickbars/plugin.min.js' // 显示一个文本框，可以进行各种操作
import 'tinymce/plugins/insertdatetime/plugin.min.js'
import 'tinymce/plugins/paste/plugin.min.js'
import 'tinymce/plugins/pagebreak/plugin.min.js'
import 'tinymce/plugins/save/plugin.min.js'
import 'tinymce/plugins/template/plugin.min.js'
import 'tinymce/plugins/hr/plugin.min.js'
import 'tinymce/plugins/anchor/plugin.min.js'
import 'tinymce/plugins/autoresize/plugin.min.js'
import 'tinymce/plugins/noneditable/plugin.min.js'

export default {
  name: "index",
  components: {
    Editor
  },
  props: {
    value: {
      type: String,
      default: ''
    },
    maxlength: {
      type: Number,
      default: 0
    },
    // 基本路径，默认为空根目录，如果你的项目发布后的地址为目录形式，
    // 即abc.com/tinymce，baseUrl需要配置成tinymce，不然发布后资源会找不到
    baseUrl: {
      type: String,
      default: import.meta.env.VITE_BASE_URL
    },
    height:{
      type: Number,
      default: 350
    },
    disabled:{
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      flag: true,
      textLength: 0,
      tinymceFlag: 1,
      // 生成随机id，用uuid可能会更好
      editorId: `editor-${Math.floor(Math.random() * 1000000)}`,
      content: '',
      // disabled: false,
      init: {
        menubar: false,
        formats: {
          p: {block: 'p', attributes: {style: "font-size: 12pt; font-family: 宋体; line-height: 1.5;"}},
          h1: {block: 'h1', attributes: {style: "font-size: 14pt; font-family: 黑体;font-weight: bold;"}},
        },
        style_formats: [
          {title: '标题', block: 'h1', styles: {'font-size': '14pt', 'font-family': '黑体', 'font-weight': 'blod'}},
        ],
        style_formats_merge: true,
        content_style: "body { font-size: 12pt; font-family: 宋体; line-height: 1.5; }",
        contextmenu: "copy paste | removeformat indent2em | link image inserttable | cell row column deletetable", // 右键菜单
        // content_css: '/tinymce/mycontent.css',
        toolbar_drawer: "sliding",
        quickbars_insert_toolbar: false,
        indentation: '24pt', // 默认缩进
        quickbars_selection_toolbar: "removeformat indent2em | bold italic underline strikethrough | forecolor backcolor", // 选中菜单
        plugins: "code link image media table advlist lists fullscreen quickbars  powerpaste print preview indent2em  anchor noneditable",
        toolbar: "undo redo | removeformat | noneditable | fullscreen | styleselect alignleft aligncenter alignright alignjustify | indent2em link anchor  | numlist bullist | print preview  | image media table | forecolor backcolor | bold italic underline strikethrough | superscript subscript",
        // plugins: 'print preview searchreplace autolink paste directionality visualblocks visualchars fullscreen image link media template code codesample table charmap hr pagebreak nonbreaking anchor insertdatetime advlist lists imagetools textpattern help emoticons autosave autoresize',
        // toolbar: 'code undo redo restoredraft | cut copy paste pastetext | forecolor backcolor bold italic underline strikethrough link anchor | alignleft aligncenter alignright alignjustify outdent indent | styleselect formatselect fontselect fontsizeselect | bullist numlist | blockquote subscript superscript removeformat | table image media charmap emoticons hr pagebreak insertdatetime print preview | fullscreen | bdmap indent2em lineheight formatpainter axupimgs',
        language_url: `${this.baseUrl}tinymce/langs/zh_CN.js`,
        language: 'zh_CN', // 本地化设置
        fullpage_default_font_size: '12pt',
        insertdatetime_formats: ['%Y年%m月%d日', '%Y-%m-%d', '%H:%M:%S'],
        skin_url: `${this.baseUrl}tinymce/skins/ui/oxide`,
        content_css: `${this.baseUrl}tinymce/skins/content/default/content.css`,
        height: this.height,
        min_height: this.height,
        width: "100%",
        branding: false, // （隐藏右下角技术支持）水印“Powered by TinyMCE”,
        promotion: false, // 去除更新？
        deprecation_warnings: false, // 隐藏warnings
        // relative_urls : false,
        // content_css : "",
        // convert_urls : false,
        // extended_valid_elements:'img[data-mce-src]',

        // image_advtab: true, // 此选项向图像对话框添加一个“高级”选项卡，允许您向图像添加自定义样式、间距和边框。
        // auto_focus: true,
        // paste_auto_cleanup_on_paste: true,
        // paste_remove_styles: true,
        // paste_remove_styles_if_webkit: true,
        // paste_strip_class_attributes: true,
        // paste_as_text: true,
        external_plugins: {
          powerpaste: `${this.baseUrl}tinymce/plugins/powerpaste/plugin.min.js`,
          indent2em: `${this.baseUrl}tinymce/plugins/indent2em/plugin.min.js`
        },
        powerpaste_word_import: 'merge',// 参数可以是propmt, merge, clear，效果自行切换对比
        powerpaste_html_import: 'merge',// propmt, merge, clear
        powerpaste_allow_local_images: true,
        powerpaste_keep_unsupported_src: true,
        // powerpaste_clean_filtered_inline_elements: 'text-indent',
        paste_merge_formats: true,
        paste_data_images: true,
        paste_convert_word_fake_lists: false, // 设为false可禁用复制word中的列表内容时，转换为html的UL或OL格式。
        paste_retain_style_properties: "text-indent", // ,margin-left
        paste_webkit_styles: "text-indent",
        indent2em_val: '24pt',
        // automatic_uploads: true,
        // images_upload_url: VITE_APP_UPLOAD_URL,
        // images_reuse_filename: true,
        // file_picker_types: 'file image media',
        images_upload_handler: (blobInfo, success, failure) => {
          const image_size = (blobInfo.blob().size / 1000) / 1024;  // image size in kbytes
          const max_size = 2;                // max size in kbytes
          if (image_size > max_size) {
            failure(`图片太大( ${image_size.toFixed(2)} Mb) ,最大图像大小为:${max_size} Mb 请先压缩图片`, {remove: true});
          } else {
            // success(`data:${  blobInfo.blob().type  };base64,${  blobInfo.base64()}`);
            const formData = new FormData();
            formData.append('file', blobInfo.blob(), blobInfo.filename());
            uploadFile(formData).then(res => {
              if (res.data) {
                success(res.data.fullFilePath)
                return
              }
              failure('上传失败数据异常', {remove: true})
            }).catch((e) => {
              failure(e.toString(), {remove: true})
            })
          }

        },
        // images_upload_handler: (blobInfo, progress) =>
        //   new Promise((resolve, reject ) => {
        //     resolve(`data:${  blobInfo.blob().type  };base64,${  blobInfo.base64()}`);
        //   }),
        // 初始化内容
        setup: (ed) => {
          // 添加自定义按钮
          ed.ui.registry.addButton('noneditable', {
            text: '锁定文本',
            onAction: function (_) {
              var content = ed.selection.getContent();
              var replacedContent = `<span class="mceNonEditable" data-locked="true">${content}</span>`;
              ed.selection.setContent(replacedContent);
            }
          });

          const allowedKeys = [8, 37, 38, 39, 40, 46]; // backspace, delete and cursor keys
          ed.on('keydown', (e) => {
            // 检查是否按下了退格键或删除键
            var node = ed.selection.getNode();
            if (node.getAttribute('data-locked') === 'true' && (e.key === 'Backspace' || e.key === 'Delete')) {
              e.preventDefault();
            }

            if (allowedKeys.indexOf(e.keyCode) !== -1) return true;
            const body = tinymce.get(this.editorId).getBody();
            let content = tinymce.trim(body.innerText || body.textContent);
            content = content.replaceAll(/\s/g, '')
            if (this.maxlength>0 && content.length + 1 > this.maxlength) {
              MessagePlugin.warning(`当前字数：${content.length}，限制字数：${this.maxlength}`);
              e.preventDefault();
              e.stopPropagation();
              return false;
            }
            return true;
          });
          // Paste Change input Undo Redo
          ed.on('PastePreProcess', (data) => {
            // const doc = new DOMParser().parseFromString(data.content, 'text/html');
            // const img = doc.getElementsByTagName("img")
            // const imgList = Array.prototype.slice.call(img);
            // imgList.forEach((val, index) => {
            //   // 如果 data-image-src 的值不为空 则替换成提示的图片
            //   // if(val.getAttribute("data-image-src")){
            //   //   val.setAttribute("width",630)
            //   //   val.setAttribute("height",200)
            //   //   val.setAttribute("src","")
            //   //   val.removeAttribute("data-image-src")
            //   // }
            //   if (!imgList[index].getAttribute("src")) {
            //     imgList[index].setAttribute("width", 550)
            //     imgList[index].setAttribute("height", 200)
            //     imgList[index].setAttribute("src", "")
            //     imgList[index].removeAttribute("data-image-src")
            //   }
            //   const img = new Image()
            //   img.src = imgList[index].getAttribute("src")
            //   if(img.width>550){
            //     imgList[index].setAttribute("width", 550)
            //     const h = (img.height * 550) / img.width
            //     imgList[index].setAttribute("height", h)
            //   }
            //   // if (!imgList[index].getAttribute("width")){
            //   //
            //   //   // console.log(img.width,img.height,"111")
            //   //   // console.log(img.naturalWidth,img.naturalHeight,"2222")
            //   // }
            //   imgList[index].style.display = 'block';
            //   imgList[index].style.marginLeft = 'auto';
            //   imgList[index].style.marginRight = 'auto';
            //
            // })
            // data.content = doc.body.innerHTML;
          })
          // ed.on('drop', (data) => {
          //
          // })
          // ed.on('PastePostProcess', (data) => {
          // });
          ed.on("Paste Change input Undo Redo keyup", (e) => {
            const body = ed.getBody();
            let content = tinymce.trim(body.innerText || body.textContent);
            content = content.replaceAll(/\s/g, '')
            this.textLength = content.length;
            this.$emit("update:textLength", this.textLength);
            const doc = this.contentFilter(ed.getBody().innerHTML)
            this.flag = ed.getContent() === '';
            this.$emit('input', ed.getContent() === '' ? '' : doc.body.innerHTML)
          })
          ed.on('init', (e) => {
            const body = ed.getBody();
            let content = tinymce.trim(body.innerText || body.textContent);
            content = content.replaceAll(/\s/g, '')
            this.textLength = content.length;
            this.$emit("update:textLength", this.textLength);

            const doc = this.contentFilter(ed.getBody().innerHTML)

            this.flag = ed.getContent() === '';
            this.$emit('input', ed.getContent() === '' ? '' : doc.body.innerHTML)
          })
        },
      }
    }
  },
  watch: {
    value: {
      handler(val) {
        if (this.flag && val) {
          this.content = val;
        }
        this.flag = true;
      },
      immediate: true,
      deep: true
    },
  },
  mounted() {
    tinymce.init({})
  },
  methods: {
    addImageProcess(src){
      return new Promise((resolve, reject) => {
        const img = new Image()
        img.onload = () => resolve({height:img.height,width:img.width})
        img.onerror = reject
        img.src = src
      })
    },
    contentFilter(bodyHtml) {
      const doc = new DOMParser().parseFromString(bodyHtml, 'text/html');
      const p = doc.getElementsByTagName("p")
      const pList = Array.prototype.slice.call(p);
      pList.forEach((val, index) => {
        pList[index].style.lineHeight = "1.5"
        pList[index].style.fontFamily = "宋体"
        pList[index].style.fontSize = "12pt"
        pList[index].removeAttribute("data-mce-style")
        // 如果有首行缩进 则重置为24pt
        if(pList[index].style?.textIndent){
          pList[index].style.textIndent = "24pt";
        }

      })
      const ol = doc.getElementsByTagName("ol")
      const olList = Array.prototype.slice.call(ol);
      olList.forEach((val, index) => {
        olList[index].style.lineHeight = "1.5"
        olList[index].style.fontFamily = "宋体"
        olList[index].style.fontSize = "12pt"
        olList[index].removeAttribute("data-mce-style")
      })
      const ul = doc.getElementsByTagName("ul")
      const ulList = Array.prototype.slice.call(ul);
      ulList.forEach((val, index) => {
        ulList[index].style.lineHeight = "1.5"
        ulList[index].style.fontFamily = "宋体"
        ulList[index].style.fontSize = "12pt"
        ulList[index].removeAttribute("data-mce-style")
      })
      const span = doc.getElementsByTagName("span")
      const spanList = Array.prototype.slice.call(span);
      spanList.forEach((val, index) => {
        if (val.getAttribute("style")) {
          spanList[index].style.lineHeight = "1.5"
          spanList[index].style.fontFamily = "宋体"
          spanList[index].style.fontSize = "12pt"
          spanList[index].style.display = null;
          spanList[index].removeAttribute("data-mce-style")
        }
      })
      const h1 = doc.getElementsByTagName("h1")
      const h1List = Array.prototype.slice.call(h1);
      h1List.forEach((val, index) => {
        h1List[index].style.fontFamily = "黑体"
        h1List[index].style.fontSize = "14pt"
        h1List[index].removeAttribute("data-mce-style")
      })
      const h2 = doc.getElementsByTagName("h2")
      const h2List = Array.prototype.slice.call(h2);
      h2List.forEach((val, index) => {
        h2List[index].style.fontFamily = "黑体"
        h2List[index].style.fontSize = "14pt"
        h2List[index].removeAttribute("data-mce-style")
      })
      const h3 = doc.getElementsByTagName("h3")
      const h3List = Array.prototype.slice.call(h3);
      h3List.forEach((val, index) => {
        h3List[index].style.fontFamily = "黑体"
        h3List[index].style.fontSize = "14pt"
        h3List[index].removeAttribute("data-mce-style")
      })
      const h4 = doc.getElementsByTagName("h4")
      const h4List = Array.prototype.slice.call(h4);
      h4List.forEach((val, index) => {
        h4List[index].style.fontFamily = "黑体"
        h4List[index].style.fontSize = "14pt"
        h4List[index].removeAttribute("data-mce-style")
      })
      const h5 = doc.getElementsByTagName("h5")
      const h5List = Array.prototype.slice.call(h5);
      h5List.forEach((val, index) => {
        h5List[index].style.fontFamily = "黑体"
        h5List[index].style.fontSize = "14pt"
        h5List[index].removeAttribute("data-mce-style")
      })
      const h6 = doc.getElementsByTagName("h6")
      const h6List = Array.prototype.slice.call(h6);
      h6List.forEach((val, index) => {
        h6List[index].style.fontFamily = "黑体"
        h6List[index].style.fontSize = "14pt"
        h6List[index].removeAttribute("data-mce-style")
      })
      // const img = doc.getElementsByTagName("img")
      // const imgList = Array.prototype.slice.call(img);
      // await Promise.all(imgList.map(async (val, index)=>{
      //   imgList[index].removeAttribute("data-mce-style")
      //   imgList[index].removeAttribute("data-mce-src")
      //   // 拖拽、外部复制的图片没有宽高
      //   if (!imgList[index].getAttribute("width") || imgList[index].getAttribute("src").includes("blob:")) {
      //     await this.addImageProcess(imgList[index].getAttribute("src")).then(res => {
      //       if(res.width>550){
      //         imgList[index].setAttribute("width", 550)
      //         const h = (res.height * 550) / res.width
      //         imgList[index].setAttribute("height", h)
      //       }
      //     })
      //   }
      // }))
      // const img = doc.getElementsByTagName("img")
      // const imgList = Array.prototype.slice.call(img);
      // imgList.forEach((val, index) => {
      //   imgList[index].removeAttribute("data-mce-style")
      //   imgList[index].removeAttribute("data-mce-src")
      //   const img = new Image()
      //   img.src =  imgList[index].getAttribute("src")
      //   if(img.width>550){
      //     imgList[index].setAttribute("width", 550)
      //     const h = (img.height * 550) / img.width
      //     imgList[index].setAttribute("height", h)
      //   }
      //   // if (!imgList[index].getAttribute("width")){
      //   //   const img = new Image()
      //   //   img.src =  imgList[index].getAttribute("src")
      //   //   if(img.width>550){
      //   //     imgList[index].setAttribute("width", 550)
      //   //     const h = (img.height * 550) / img.width
      //   //     imgList[index].setAttribute("height", h)
      //   //   }
      //   // }
      //   // imgList[index].style.display = 'block';
      //   // imgList[index].style.marginLeft = 'auto';
      //   // imgList[index].style.marginRight = 'auto';
      // })
      return doc
    }
  },
}
</script>

<style lang="less" scoped>
.text-length-wrapper {
  position: relative;
  //height: 22px;

  .text-length {
    position: absolute;
    bottom: 0px;
    right: 16px;
  }
}
// skins ui skin.min.css 修改
///deep/ .tox-tinymce-aux {
//  z-index: 19891014;
//}
</style>
